/*
 *  author: Honrun
 */
#include "stdint.h"
#include "stdio.h"
#include "n32g031.h"
#include "DevicesList.h"
#include "DevicesTime.h"
#include "DevicesSoftTimer.h"



/* 软件定时器状态机的头节点 */
ListType g_typeListSoftTimerHead = {&g_typeListSoftTimerHead, &g_typeListSoftTimerHead, LIST_VALUE_MAX, NULL};



int8_t cSoftTimerSet(SoftTimerTypeDef *ptypeTimer, int64_t lTime, SoftTimerStateEnum state)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop = lSoftTimerGetNow() + lTime;
    ptypeTimer->timeDuration = lTime;
    ptypeTimer->state = state;

    return 0;
}

int8_t cSoftTimerReset(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cSoftTimerSet(ptypeTimer, ptypeTimer->timeDuration, ptypeTimer->state | softTimerOpen);

    return 0;
}

int8_t cSoftTimerReload(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->timeStop += ptypeTimer->timeDuration;
    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerOpen(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state |= softTimerOpen;

    return 0;
}

int8_t cSoftTimerClose(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state &= ~softTimerOpen;

    return 0;
}

int8_t cSoftTimerSetState(SoftTimerTypeDef *ptypeTimer, SoftTimerStateEnum enumState)
{
    if(ptypeTimer == NULL)
        return -1;

    ptypeTimer->state = enumState;

    /* 设置为本次立即触发 */
    if(enumState & softTimerOver)
        ptypeTimer->timeStop = lSoftTimerGetNow();

    return 0;
}

SoftTimerStateEnum enumSoftTimerGetState(SoftTimerTypeDef *ptypeTimer)
{
    int64_t lTimeNow = 0;

    if(ptypeTimer == NULL)
        return softTimerError;

    if((ptypeTimer->state & softTimerOpen) == 0)
        return softTimerClose;

    lTimeNow = lSoftTimerGetNow();

    if(lTimeNow >= (ptypeTimer->timeStop))
        return softTimerOver;

    return softTimerOpen;
}

/* 单位us */
int64_t lSoftTimerGetNow(void)
{
    int64_t lTimeStamp = 0;

    lTimeStamp = lTimeGetStamp();

    return lTimeStamp;
}







int8_t cSoftTimerCreate(SoftTimerTypeDef *ptypeTimer, int64_t lTime, SoftTimerStateEnum state, void (*vCallbackFunction)(void *pvHandle))
{
    int8_t cError = 0;

    if(ptypeTimer == NULL)
        return -1;

    cError |= cSoftTimerSetUs(ptypeTimer, lTime, state);

    cError |= cListInit(&(ptypeTimer->typeList), ptypeTimer->timeStop);

    /* 按顺序插入 */
    cError |= cListInsert(&g_typeListSoftTimerHead, &(ptypeTimer->typeList));

    ptypeTimer->typeList.pElement = ptypeTimer;

    ptypeTimer->vCallbackFunction = vCallbackFunction;

    return cError;
}

int8_t cSoftTimerRemove(SoftTimerTypeDef *ptypeTimer)
{
    if(ptypeTimer == NULL)
        return -1;

    cListRemove(&(ptypeTimer->typeList));

    return 0;
}

int8_t cSoftTimerMachine(void)
{
    ListType *ptypeListNow = g_typeListSoftTimerHead.pNext;
    SoftTimerTypeDef *ptypeTimerNow = NULL;
    int8_t cError = 0;

    while(ptypeListNow != &g_typeListSoftTimerHead)
    {
        ptypeTimerNow = ptypeListNow->pElement;
        if(enumSoftTimerGetState(ptypeTimerNow) == softTimerOver)
        {
            /* 回调函数 */
            if(ptypeTimerNow->vCallbackFunction != NULL)
            {
                ptypeTimerNow->vCallbackFunction(ptypeTimerNow);
            }

            /* 重复计时 */
            if(ptypeTimerNow->state & softTimerCircular)
            {
                cError |= cSoftTimerReload(ptypeTimerNow);
            }
            /* 单次计时 */
            else
            {
                cError |= cSoftTimerClose(ptypeTimerNow);
            }
        }

        ptypeListNow = ptypeListNow->pNext;
    }

    return cError;
}
